home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / comm / pipeln10.zip / AQUEDUCT.ASM next >
Assembly Source File  |  1990-06-01  |  12KB  |  386 lines

  1. ;**************************************************************************
  2. ;*     AQUEDUCT vers 1.20, DOS                                            *
  3. ;*     Connects COM1 and COM2 in software.                                *
  4. ;*     6/1/90                                                             *
  5. ;*     by James W. Birdsall                                               *
  6. ;*                                                                        *
  7. ;*     assembles under Turbo Assembler 1.0, 2.0                           *
  8. ;*                                                                        *
  9. ;*     requires DOS 2.0 or higher                                         *
  10. ;*                                                                        *
  11. ;*   This program is a small TSR that connects COM1 and COM2 in software. *
  12. ;*   It is run from the command line with no arguments. After             *
  13. ;*   installation, setup and activation is performed with the program     *
  14. ;*   VALVE.                                                               *
  15. ;*                                                                        *
  16. ;*   This program can share an interrupt vector. It can be set to chain   *
  17. ;*   to the previous interrupt handler if examination of the serial port  *
  18. ;*   shows that no interrupt is pending.                                  *
  19. ;*                                                                        *
  20. ;**************************************************************************
  21.  
  22. LOCALS
  23. .MODEL tiny
  24.  
  25.  
  26. ENVOFFSET    EQU    2Ch
  27.  
  28. INTERFACEINT    EQU    0F1h
  29.  
  30. BUFFERLENGTH    EQU    8
  31. BUFFERLENMASK    EQU    08h
  32. BUSY1READ       EQU     01h
  33. BUSY1SEND    EQU     02h
  34. BUSY2READ    EQU    04h
  35. BUSY2SEND    EQU    08h
  36.  
  37.  
  38. ; TO CHANGE FROM COM1 OR COM2, CHANGE THE FOLLOWING INTERRUPT AND PORT
  39. ; VALUES.
  40. COM1INT        EQU    0Ch
  41. COM2INT        EQU    0Bh
  42.  
  43. COM1BASE    EQU    3F8h
  44. COM1IER        EQU    3F9h
  45. COM1IIR        EQU    3FAh
  46. COM1LSR        EQU    3FDh
  47.  
  48. COM2BASE    EQU    2F8h
  49. COM2IER        EQU    2F9h
  50. COM2IIR        EQU    2FAh
  51. COM2LSR        EQU    2FDh
  52. ; END OF INTERRUPT AND PORT VALUES
  53.  
  54.  
  55. EOI        EQU    20h
  56. EOIPORT        EQU    20h
  57.  
  58. RDAINT        EQU    04h
  59. THREINT        EQU    02h
  60. RDAENABLE    EQU    01h
  61. BOTHENABLE    EQU    03h
  62. OVERRUNMASK    EQU    02h
  63. INTPENDMASK    EQU    01h
  64.  
  65.  
  66. .CODE
  67.     ORG    100h
  68. start:
  69.     jmp    Install            ; jump to installation code
  70.  
  71. ; DATA AREA
  72.  
  73. errors        dw    0
  74. int_B        dd    0
  75. old_int_B    dd    0
  76. int_C        dd    0
  77. old_int_C    dd    0
  78. PSPseg        dw    0
  79. old_interface    dd    0
  80. enabled         db      0
  81. chain        db    0
  82. one_in_head    dw    0
  83. one_in_tail    dw    0
  84. two_in_head    dw    0
  85. two_in_tail    dw    0
  86. busyflag        db      0
  87. one_in        db    BUFFERLENGTH dup (?)
  88. two_in        db    BUFFERLENGTH dup (?)
  89.  
  90.  
  91. ; HANDLER FOR COM1 INTERRUPTS
  92.  
  93. Com1handler:
  94.     sti                ; enable interrupts
  95.         push    ax            ; preserve
  96.         push    bx
  97.         push    dx
  98.  
  99.         mov    dx, COM1LSR        ; check for overruns
  100.         in    al, dx
  101.         test    al, OVERRUNMASK
  102.         jz    @@NoOverrun        ; if zero, OK
  103.         inc    cs:errors        ; else increment ERRORS
  104. @@NoOverrun:
  105.     mov    dx, COM1IIR        ; read interrupt id
  106.         in    al, dx
  107.         test    al, INTPENDMASK        ; is our interrupt?
  108.         jz    @@Ours            ; if zero, ours
  109.         jmp    @@NotOurs        ; else not
  110. @@Ours:
  111.         cmp    al, RDAINT        ; is received char?
  112.         je    @@Received
  113.         cmp    al, THREINT        ; is send?
  114.         je    @@Transmit
  115.         jmp    @@SendEOI        ; if unknown, send EOI
  116.  
  117. @@Received:
  118.     mov    dx, COM1BASE        ; read character
  119.         in    al, dx
  120.     test    cs:busyflag, BUSY2SEND    ; is port 2 sending?
  121.         jz    @@OkToRead        ; if zero, go ahead
  122.         inc    cs:errors        ; else increment errors
  123.         jmp    @@SendEOI        ; and send EOI
  124. @@OkToRead:
  125.     or    cs:busyflag, BUSY1READ    ; set flag
  126.         mov    bx, cs:one_in_head    ; get index
  127.         mov    cs:one_in + bx, al    ; put char in buffer
  128.         inc    cs:one_in_head            ; increment index
  129.         test    cs:one_in_head, BUFFERLENMASK    ; check for index overflow
  130.         jz    @@ReadDone            ; if no overflow, jump
  131.         mov    cs:one_in_head, 0    ; else zero index
  132. @@ReadDone:
  133.         mov    dx, COM2IER        ; read interrupt enable
  134.         in    al, dx
  135.         cmp    al, BOTHENABLE        ; THRE already on?
  136.         je    @@ReadDone2        ; do nothing
  137.         mov    al, BOTHENABLE        ; else enable it
  138.         xor     cs:busyflag, BUSY1READ  ; reset flag just before enabling int
  139.         out    dx, al
  140.         jmp    @@SendEOI        ; and jump
  141. @@ReadDone2:
  142.     xor    cs:busyflag, BUSY1READ    ; reset flag
  143.         jmp    @@SendEOI
  144.  
  145. @@Transmit:
  146.     test    cs:busyflag, BUSY2READ    ; is port 2 reading?
  147.         jz    @@OkToSend        ; if zero, go ahead
  148.         or      cs:busyflag, BUSY1SEND
  149.         jmp    @@NoTrans        ; otherwise shut down sending
  150. @@OkToSend:
  151.     or    cs:busyflag, BUSY1SEND    ; set flag
  152.         mov    bx, cs:two_in_tail    ; set index
  153.         cmp    bx, cs:two_in_head    ; are chars to send?
  154.         je    @@NoTrans        ; if not, shut down sending
  155.         mov    al, cs:two_in + bx    ; else move char to AL
  156.         mov    dx, COM1BASE
  157.         out    dx, al
  158.         inc    cs:two_in_tail            ; increment index
  159.         test    cs:two_in_tail, BUFFERLENMASK    ; check for overflow
  160.         jz    @@SentOK            ; if no overflow, jump
  161.         mov    cs:two_in_tail, 0    ; else zero index
  162. @@SentOK:
  163.     xor    cs:busyflag, BUSY1SEND    ; reset flag
  164.         jmp    @@SendEOI
  165. @@NoTrans:
  166.     mov    dx, COM1IER        ; read interrupt enable
  167.         in    al, dx
  168.         cmp    al, RDAENABLE        ; RDA only already?
  169.         je    @@NoTrans2        ; if so, do nothing
  170.         mov    al, RDAENABLE        ; else enable RDA only
  171.         out    dx, al
  172.         jmp    @@NoTrans2        ; and jump
  173. @@NoTrans2:
  174.     xor    cs:busyflag, BUSY1SEND    ; reset flag
  175.         jmp    @@SendEOI        ; and jump
  176.  
  177. @@NotOurs:
  178.     test    cs:chain, 0FFh        ; is chain zero?
  179.         jz    @@SendEOI        ; if so, return normally
  180.         pushf                ; preserve flags
  181.         call    cs:old_int_C        ; call old handler
  182.         jmp    @@Final            ; and return
  183.  
  184. @@SendEOI:
  185.     mov    al, EOI            ; send EOI
  186.         out    EOIPORT, al
  187.  
  188. @@Final:
  189.     pop    dx            ; restore
  190.         pop    bx
  191.         pop    ax
  192.         iret                ; return
  193.  
  194.  
  195. ; HANDLER FOR COM2 INTERRUPTS
  196.  
  197. Com2handler:
  198.     sti                ; enable interrupts
  199.         push    ax            ; preserve
  200.         push    bx
  201.         push    dx
  202.  
  203.         mov    dx, COM2LSR        ; check for overruns
  204.         in    al, dx
  205.         test    al, OVERRUNMASK
  206.         jz    @@NoOverrun        ; if zero, OK
  207.         inc    cs:errors        ; else increment ERRORS
  208. @@NoOverrun:
  209.     mov    dx, COM2IIR        ; read interrupt id
  210.         in    al, dx
  211.         test    al, INTPENDMASK        ; is our interrupt?
  212.         jz    @@Ours            ; if zero, ours
  213.     jmp    @@NotOurs        ; else not
  214. @@Ours:
  215.         cmp    al, RDAINT        ; is received char?
  216.         je    @@Received
  217.         cmp    al, THREINT        ; is send?
  218.         je    @@Transmit
  219.         jmp    @@SendEOI        ; if unknown, send EOI
  220.  
  221. @@Received:
  222.     mov    dx, COM2BASE        ; read character
  223.         in    al, dx
  224.     test    cs:busyflag, BUSY1SEND    ; is port 1 sending?
  225.         jz    @@OkToRead        ; if zero, go ahead
  226.         inc    cs:errors        ; else increment errors
  227.         jmp    @@SendEOI        ; and send EOI
  228. @@OkToRead:
  229.     or    cs:busyflag, BUSY2READ    ; set flag
  230.         mov    bx, cs:two_in_head    ; get index
  231.         mov    cs:two_in + bx, al    ; put char in buffer
  232.         inc    cs:two_in_head            ; increment index
  233.         test    cs:two_in_head, BUFFERLENMASK    ; check for index overflow
  234.         jz    @@ReadDone            ; if no overflow, jump
  235.         mov    cs:two_in_head, 0    ; else zero index
  236. @@ReadDone:
  237.         mov    dx, COM1IER        ; read interrupt enable
  238.         in    al, dx
  239.         cmp    al, BOTHENABLE        ; THRE already on?
  240.         je    @@ReadDone2        ; do nothing
  241.         mov    al, BOTHENABLE        ; else enable it
  242.         out    dx, al
  243.         jmp    @@ReadDone2        ; and jump
  244. @@ReadDone2:
  245.     xor    cs:busyflag, BUSY2READ    ; reset flag
  246.         jmp    @@SendEOI        ; and jump
  247.  
  248. @@Transmit:
  249.     test    cs:busyflag, BUSY1READ    ; is port 1 reading?
  250.         jz    @@OkToSend        ; if zero, go ahead
  251.         or    cs:busyflag, BUSY2SEND    ; set flag
  252.         jmp    @@NoTrans        ; otherwise shut down sending
  253. @@OkToSend:
  254.     or    cs:busyflag, BUSY2SEND    ; set flag
  255.         mov    bx, cs:one_in_tail    ; set index
  256.         cmp    bx, cs:one_in_head    ; are chars to send?
  257.         je    @@NoTrans        ; if not, shut down sending
  258.         mov    al, cs:one_in + bx    ; else move char to AL
  259.         mov    dx, COM2BASE
  260.         out    dx, al
  261.         inc    cs:one_in_tail            ; increment index
  262.         test    cs:one_in_tail, BUFFERLENMASK    ; check fo